extends CharacterBody2D

@export var MaxHP : float = 51
@export var CurrentHP : float = 51
@export var MaxMP : float = 24
@export var CurrentMP : float = 24
@export var Title : String = "GM"
@export var PlayerName : String = "测试测试小神仙"
@export var Level : int = 1  # 等级
@export var player_current_exp : int = 0  # 当前经验值
@export var player_max_exp : int = 1  # 当前等级的最大经验值
@export var attack_distance : float = 230.0  # 攻击距离
@export var action_interval : float = 0.8   # 行动间隔时间
@export var player_damage : float = 10.0    # 玩家攻击伤害


@onready var hp_bar: TextureProgressBar = $RoleBG/HPBar
@onready var hp_label: Label = $RoleBG/HPBar/HPLabel
@onready var mp_bar: TextureProgressBar = $RoleBG/MPBar
@onready var mp_label: Label = $RoleBG/MPBar/MPLabel
@onready var title_label: Label = $RoleBG/TitleLabel
@onready var lv_label: Label = $RoleBG/LVBG/LVLabel
@onready var player_name: Label = $RoleBG/PlayerName

# 移动状态控制
var is_moving: bool = false
var is_attacking: bool = false
var action_timer: Timer
var monsters = []  # 存储所有怪物引用
var current_target: Node = null  # 当前目标怪物
var is_locked_on_target: bool = false  # 是否已锁定目标
var horizontal_move_distance: float = 120.0  # 左右移动距离
var vertical_move_distance: float = 130.0    # 上下移动距离
var attack_move_distance: float = 5.0        # 攻击位移距离(单位：像素)

# 添加经验值变化信号
signal exp_changed(current_exp, max_exp)

# 射线检测方向
@onready var raycasts = {
	"up": $RayCastUp,
	"down": $RayCastDown,
	"left": $RayCastLeft,
	"right": $RayCastRight
}

var exp_table : Dictionary = {  # 等级-经验值对照表
	1: 50,  # 1级升2级需要50经验
	2: 88,
	3: 199,
	4: 403,
	5: 549,
	6: 853,
	7: 1204,
	8: 1502,
	9: 1750,
	10: 2149,
	11: 5416,
	12: 6386,
	13: 7512,
	14: 8918,
	15: 10663,
	16: 12819,
	17: 15300,
	18: 17838,
	19: 20096,
	20: 23093,
	21: 29825,
	22: 32921,
	23: 35186,
	24: 41334,
	25: 43843,
	26: 48108,
	27: 54326,
	28: 59737,
	29: 64876,
	30: 258233
}


func _ready() -> void:
	# 初始化玩家最大经验值
	if Level in exp_table:
		player_max_exp = exp_table[Level]
	else:
		# 如果等级超出表格，使用公式计算
		player_max_exp = Level * 100
	
	update_Data()
	# 初始化后发出经验值信号
	emit_signal("exp_changed", player_current_exp, player_max_exp)
	
	# 初始化行动计时器
	action_timer = Timer.new()
	add_child(action_timer)
	action_timer.wait_time = action_interval
	action_timer.timeout.connect(_on_action_timer_timeout)
	action_timer.start()
	
	# 获取所有怪物
	update_monsters_list()

# 更新怪物列表
func update_monsters_list():
	monsters = get_tree().get_nodes_in_group("monster")

func _on_action_timer_timeout():
	if is_moving or is_attacking:
		return
	
	update_monsters_list()
	
	# 过滤掉无效怪物
	monsters = monsters.filter(func(m): return is_instance_valid(m) and m)
	
	if monsters.size() == 0:
		is_locked_on_target = false  # 重置锁定状态
		current_target = null
		return
	
	# 如果已经锁定目标且目标仍然有效
	if is_locked_on_target and current_target and is_instance_valid(current_target):
		var distance = global_position.distance_to(current_target.global_position)
		if distance <= attack_distance:
			_attack_monster(current_target)
		else:
			_move_towards_monster(current_target)
		return
	
	# 如果没有锁定目标，则寻找新目标
	is_locked_on_target = false  # 确保重置锁定状态
	var closest_monster = null
	var min_distance = INF
	
	for monster in monsters:
		var distance = global_position.distance_to(monster.global_position)
		if distance < min_distance:
			min_distance = distance
			closest_monster = monster
	
	if closest_monster:
		# 锁定这个新目标
		current_target = closest_monster
		is_locked_on_target = true
		
		if min_distance <= attack_distance:
			_attack_monster(closest_monster)
		else:
			_move_towards_monster(closest_monster)

# 攻击怪物
func _attack_monster(monster):
	if is_attacking or not monster:
		return
	
	is_attacking = true
	var original_position = position
	
	# 计算攻击方向
	var attack_direction = (monster.global_position - global_position).normalized()
	var attack_target = position + attack_direction * attack_move_distance  # 小幅度攻击位移
	
	# 创建攻击动画Tween
	var attack_tween = create_tween()
	attack_tween.set_trans(Tween.TRANS_BACK)
	
	# 向前攻击
	attack_tween.tween_property(self, "position", attack_target, 0.1)
	# 返回原位
	attack_tween.tween_property(self, "position", original_position, 0.1)
	
	# 动画完成后执行实际攻击
	attack_tween.tween_callback(_on_attack_animation_completed)
	
	print("攻击怪物: ", monster.monster_name)

# 攻击动画完成回调
func _on_attack_animation_completed():
	is_attacking = false
	if current_target and is_instance_valid(current_target):
		_deal_damage_to_monster(current_target)

# 实际伤害处理
func _deal_damage_to_monster(monster):
	if is_instance_valid(monster):
		monster.take_damage(player_damage)
		
		# 检查目标是否死亡
		if monster.monster_currentHP <= 0:
			# 目标已死亡，重置锁定状态
			is_locked_on_target = false
			current_target = null

# 向怪物移动
func _move_towards_monster(monster):
	if is_moving or not monster:
		return
	
	# 获取最佳移动方向
	var direction = _get_best_direction_towards(monster.global_position)
	
	if direction == Vector2.ZERO:
		return
	
	# 再次确认方向是否被阻挡
	if _is_direction_blocked(direction):
		return
	
	is_moving = true
	
	# 计算目标位置
	# 根据方向决定移动距离
	var move_dist = vertical_move_distance if direction.y != 0 else horizontal_move_distance
	var target_position = global_position + direction * move_dist
	
	# 使用 Tween 平滑移动
	var tween = create_tween()
	tween.tween_property(self, "global_position", target_position, 0.5)
	tween.tween_callback(_on_move_completed)
	
	print("向怪物移动: ", direction)

# 移动完成回调
func _on_move_completed():
	is_moving = false

# 获取朝向目标的最佳方向
func _get_best_direction_towards(target_position: Vector2) -> Vector2:
	var direction_to_target = (target_position - global_position).normalized()
	
	# 只考虑上下左右四个方向
	var possible_directions = [
		Vector2.UP,
		Vector2.DOWN,
		Vector2.LEFT,
		Vector2.RIGHT
	]
	
	# 选择最接近目标方向的有效方向
	var best_direction = Vector2.ZERO
	var best_dot = -INF
	
	for dir in possible_directions:
		if not _is_direction_blocked(dir):
			var dot = direction_to_target.dot(dir)
			if dot > best_dot:
				best_dot = dot
				best_direction = dir
	
	return best_direction

# 检查指定方向是否有障碍物
func _is_direction_blocked(direction: Vector2) -> bool:
	var raycast = null
	
	if direction == Vector2.UP:
		raycast = raycasts["up"]
	elif direction == Vector2.DOWN:
		raycast = raycasts["down"]
	elif direction == Vector2.LEFT:
		raycast = raycasts["left"]
	elif direction == Vector2.RIGHT:
		raycast = raycasts["right"]
	
	if raycast:
		raycast.force_raycast_update()
		if raycast.is_colliding():
			var collider = raycast.get_collider()
			# 检查是否是其他Area2D或障碍物
			if collider is Area2D or collider is StaticBody2D:
				if collider != self:  # 排除自己
					return true
	return false

func take_damage(damage: float):
	CurrentHP -= damage
	update_Data()
	# 添加受伤效果
	_play_hurt_effect()
	# 检查死亡
	if CurrentHP <= 0:
		# 死亡时从组中移除 - 添加这行
		remove_from_group("player")
		queue_free()

func _play_hurt_effect():
	# 简单的受伤闪烁效果
	var tween = create_tween()
	tween.tween_property(self, "modulate", Color.RED, 0.1)
	tween.tween_property(self, "modulate", Color.WHITE, 0.1)

func gain_exp(exp_amount: int):
	player_current_exp += exp_amount
	print("获得经验: ", exp_amount, " | 当前经验: ", player_current_exp, "/", player_max_exp)
	
	# 发出经验值变化信号
	emit_signal("exp_changed", player_current_exp, player_max_exp)
	
	# 检查是否升级
	var leveled_up = false
	while player_current_exp >= player_max_exp and player_max_exp > 0:
		# 升级
		player_current_exp -= player_max_exp
		Level += 1
		leveled_up = true
		
		# 计算新等级的最大经验值
		if Level in exp_table:
			player_max_exp = exp_table[Level]
		else:
			# 如果等级超出表格，使用公式计算
			player_max_exp = Level * 200
		
		# 更新玩家属性
		MaxHP = 41 + Level * 10
		CurrentHP = MaxHP  # 升级时恢复满血
		MaxMP = 21 + Level * 2
		CurrentMP = MaxMP  # 升级时恢复满蓝
		player_damage = 20 + Level * 5
		
		print("升级! 当前等级: ", Level)
	
	if leveled_up:
		# 更新UI
		update_Data()
		# 发出经验值变化信号（因为升级后最大经验值变化）
		emit_signal("exp_changed", player_current_exp, player_max_exp)
		# 显示升级特效
		_show_level_up_effect()

# 显示升级特效
func _show_level_up_effect():
	# 创建闪烁效果
	var tween = create_tween()
	tween.set_parallel(true)  # 并行执行
	
	# 颜色闪烁
	tween.tween_property(self, "modulate", Color(0.5, 1.0, 1.0), 0.1)
	tween.tween_property(self, "modulate", Color.WHITE, 0.3).set_delay(0.1)
	
	# 缩放效果
	tween.tween_property(self, "scale", Vector2(1.2, 1.2), 0.1)
	tween.tween_property(self, "scale", Vector2(1.0, 1.0), 0.3).set_delay(0.1)
	
	# 添加文字效果（可选）
	var label = Label.new()
	label.text = "LEVEL UP!"
	label.position = Vector2(0, 0)
	label.modulate = Color(0.2, 0.8, 1.0)
	add_child(label)
	
	# 文字动画
	var label_tween = create_tween()
	label_tween.tween_property(label, "position:y", -150, 1.0)
	label_tween.tween_property(label, "modulate:a", 0.0, 0.5)
	label_tween.tween_callback(label.queue_free)

func update_Data():
	hp_label.text = str(int(CurrentHP)) + " / " + str(int(MaxHP))
	hp_bar.value = CurrentHP / MaxHP * 100
	mp_label.text = str(int(CurrentMP)) + " / " + str(int(MaxMP))
	mp_bar.value = CurrentMP / MaxMP * 100
	title_label.text = str(Title)
	lv_label.text = str(Level)
	player_name.text = PlayerName
	
